package br.com.winesys.geta.databinding.component.table;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import br.com.winesys.geta.base.ExceptionMessage;
import br.com.winesys.geta.databinding.component.listeners.SelectionListener;
import br.com.winesys.geta.dialog.ObjectActionDialog;
import br.com.winesys.geta.editor.Editor;

public class TableEditor<Entity> extends JPanel {

    private JPanel buttonsPanel;
    private JButton addButton;
    private JButton editButton;
    private JButton deleteButton;
    private TableViewer<Entity> tableViewer;
    private TableModel<Entity> tableModel;
    private Editor<Entity> editor;
    private Class<Entity> itemClass;
    private Entity selected;

    public TableEditor(TableModel<Entity> tableModel, Editor<Entity> editor, Class<Entity> itemClass) {
        this.tableModel = tableModel;
        this.editor = editor;
        this.itemClass = itemClass;
        this.tableViewer = new TableViewer<Entity>(JTable.AUTO_RESIZE_ALL_COLUMNS, false) {

            @Override
            protected TableModel<Entity> createTableModel() {
                return TableEditor.this.tableModel;
            }

            @Override
            protected Editor<?> createFilter() {
                return null;
            }
        };
        this.tableViewer.addSelectionListener(new SelectionListener<Entity>() {

            @Override
            public void itemSelected(Entity object) {
                TableEditor.this.selected = object;
                TableEditor.this.editButton.setEnabled(object != null);
                TableEditor.this.deleteButton.setEnabled(object != null);
            }
        });
        this.addButton = new JButton(new ImageIcon(getClass().getResource("/images/new-small.png")));
        this.editButton = new JButton(new ImageIcon(getClass().getResource("/images/edit-small.png")));
        this.deleteButton = new JButton(new ImageIcon(getClass().getResource("/images/delete-small.png")));

        this.editButton.setEnabled(false);
        this.deleteButton.setEnabled(false);

        this.buttonsPanel = new JPanel();
        this.buttonsPanel.setLayout(new FlowLayout());
        this.buttonsPanel.add(this.addButton);
        this.buttonsPanel.add(this.editButton);
        this.buttonsPanel.add(this.deleteButton);
        this.buttonsPanel.doLayout();

        this.setLayout(new BorderLayout());
        this.add(this.tableViewer, BorderLayout.NORTH);
        this.add(this.buttonsPanel, BorderLayout.SOUTH);
        this.doLayout();

        this.addButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                TableEditor.this.doAdd();
            }
        });

        this.editButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                TableEditor.this.doEdit();
            }
        });

        this.deleteButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                TableEditor.this.doDelete();
            }
        });
    }

    private void doAdd() {
        ObjectActionDialog<Entity> dlg = new ObjectActionDialog<Entity>(SwingUtilities.getWindowAncestor(this), "Adicionar") {

            @Override
			public Editor<Entity> createObjectEditor() {
                return TableEditor.this.editor;
            }

			@Override
			protected Entity newInstance() {
				try {
					return TableEditor.this.itemClass.newInstance();
				} catch (Exception ex) {
					throw new RuntimeException(ex);
				}
			}

			@Override
			protected boolean execute(Entity objectAction) {
                TableEditor.this.tableModel.addValue(objectAction);
                return true;
			}
        };
        try {
            dlg.run(this.itemClass.newInstance());
        } catch (Exception ex) {
            Toolkit.getDefaultToolkit().beep();
            JOptionPane.showMessageDialog(this, ExceptionMessage.getMessage(ex), "Erro", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void doEdit() {
        ObjectActionDialog<Entity> dlg = new ObjectActionDialog<Entity>(SwingUtilities.getWindowAncestor(this), "Alterar") {

            @Override
			public Editor<Entity> createObjectEditor() {
                return TableEditor.this.editor;
            }

			@Override
			protected Entity newInstance() {
				try {
		            TableEditor.this.itemClass.newInstance();
		        } catch (Exception ex) {
		            throw new RuntimeException(ex);
		        }
		        return null;
			}

			@Override
			protected boolean execute(Entity objectAction) {
                TableEditor.this.tableModel.fireTableDataChanged();
                return true;
			}
        };
        dlg.run(this.selected);
    }

    private void doDelete() {
        if (JOptionPane.showConfirmDialog(this, "Tem certeza que deseja excluir o item?", "Excluir", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
            this.tableModel.removeValue(this.selected);
        }
    }

    public void setValues(List<Entity> values) {
        this.tableModel.setValues(values);
    }

    public List<Entity> getValues() {
        return this.tableModel.getValues();
    }
}
